Skip to main content

Javascript decoder

The Spirit LoRaWAN Radon Detector sends data compressed in a hex string format. To interpret this data, you need to use a JSON decoder in your LoRaWAN network server. Below is the JSON decoder that you can use to decode the payload sent by the Spirit device.

This decoder is usually inserted at your network server under Payload formatter or similar.




function byteToBinary(byte) {
if (byte === null || byte === undefined || isNaN(byte)) {
return "00000000";
}
return (byte & 0xFF).toString(2).padStart(8, "0");
}

function safeByte(bytes, index) {
return index < bytes.length ? bytes[index] : 0;
}

function decodeUplink(input) {
// Only decode payload if fPort === 5
if (input.fPort !== 5) {
return {
data: {},
warnings: [`Skipped decoding for port ${input.fPort}`],
errors: []
};
}

const bytes = input.bytes;

function getSerieId() {
return ((safeByte(bytes, 3) & 0x03) << 2) |
((safeByte(bytes, 2) & 0xf0) >> 4);
}

function getPacketNumber() {
return ((safeByte(bytes, 2) & 0x0f) << 16) |
(safeByte(bytes, 1) << 8) |
safeByte(bytes, 0);
}

function getRadonLevel() {
return 5*(((safeByte(bytes, 5) & 0x0f) << 10) |
(safeByte(bytes, 4) << 6) |
((safeByte(bytes, 3) & 0xfc) >> 2));
}

function getUncertainty() {
return 5*(((safeByte(bytes, 7) & 0x0f) << 12) |
(safeByte(bytes, 6) << 4) |
((safeByte(bytes, 5) & 0xf0) >> 4));
}

function getTemp() {
return safeByte(bytes, 8) / 2.0 - 40.0;
}

function getHumidity() {
return safeByte(bytes, 9) / 2.0;
}

function getPressure() {
return safeByte(bytes, 10) + 900;
}

function getVoltage() {
return safeByte(bytes, 11) * 10 + 2500;
}

function getStatusBits() {
return byteToBinary(safeByte(bytes, 12));
}

function parseStatus(statusBits) {
return {

tampering: statusBits[5] === "1",
errorExists: statusBits[4] === "1",
charging: statusBits[3] === "1",
onBattery: statusBits[7] === "1",
radonSensorOff: statusBits[6] === "0",
};
}

const statusBits = getStatusBits();
const status = parseStatus(statusBits);

return {
data: {
measureSerieId: getSerieId(),
packetNumber: getPacketNumber(),
radonLevel: getRadonLevel(),
radonLevelUncertainty: getUncertainty(),

temperature: getTemp(),
relativeHumidity: getHumidity(),
pressure: getPressure(),
voltage: getVoltage(),

onBattery: status.onBattery,
radonSensorOn: !status.radonSensorOff,
tampering: status.tampering,
batteryCharging: status.charging,
errorExists: status.errorExists,
},
warnings: [],
errors: []
};
}